require "Global"
require "TMXTiledMap"
require "LocalPlayer"
require "Protocol"

server_ip = "5.147.240.184"
server_port = 11390
-- avoid memory leak
collectgarbage("setpause", 100)
collectgarbage("setstepmul", 5000)

--World class
World = {
	localPlayerID = nil,
	players = nil,
	map = nil,
	updateID = nil,
	msgProcess = nil,
}

World.__index = World

function World:onEnter()
	Misc:log("World : onEnter .. " .. Misc:getNodeName(self))
	
	local function onTouches(eventType, touches)
		if eventType == CCTOUCHBEGAN then
            self:onTouchesBegin(touches)
		elseif eventType == CCTOUCHMOVED then
            self:onTouchesMoved(touches)
		else
            --onTouchEnded(touches[1], touches[2])
		end
	end
		
    self:registerScriptTouchHandler(onTouches, true, 1, true)
	self:setTouchEnabled(true)
	
	--network
    CNetManager:getInstancePtr():loginServer(server_ip, server_port, "gzy1", "12345")
    
    local function receiveMsg(msgType)
		self:receiveMsg(msgType)
    end
    local function sendMsg(msgType)
		self:sendMsg(msgType)
    end
    self.msgProcess = CPlayerMsgProcess:getInstancePtr()
    self.msgProcess:setReceiveFunc(receiveMsg);
    self.msgProcess:setSendFunc(sendMsg);
    
	local function update(dt)
		self:tick(dt)
    end	
	self.updateID = CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(update, 1/60.0, false)
end

function World:tick(dt)
	CNetManager:getInstancePtr():tick()
end

function World:onExit()
	CCDirector:sharedDirector():getScheduler():unscheduleScriptEntry(self.updateID)
end

function World:create(playerFile)
	local newWorld = {}
	setmetatable(newWorld, self)
	--self.__index = self
	
	local scene = CCScene:create()
	CCDirector:sharedDirector():runWithScene(scene)
	local ccWorld = CCLayer:create()
	scene:addChild(ccWorld)
	tolua.setpeer(ccWorld, newWorld)
	
	ccWorld.map = TMXTiledMap:create("map1/map_0_0.tmx", Misc:fullPathFile("map1/map_0_0.bld"))--CCTMXTiledMap:create("map1/map_0_0.tmx")
	ccWorld:addChild(ccWorld.map)
	
	ccWorld.players={}
	
	local function onEnterOrExit(eventType)
		if eventType == kCCNodeOnExit then
			ccWorld:onExit()
		else
			ccWorld:onEnter()
		end
	end
	
	ccWorld:registerScriptHandler(onEnterOrExit)
	
	if ccWorld:isRunning() then
		ccWorld:onEnter()
	end
	return ccWorld
end

function World:onTouchesMoved(touches)
	local pt1 = CCPoint(touches[1], touches[2])
	lastPos = pt1
end
	

function World:onTouchesBegin(touches)
	local pt1 = CCPoint(touches[1], touches[2])
	local mapPos = self.map:convertToNodeSpace(pt1)
	--self.players[localPlayerID]:moveTo(mapPos)
	self.msgProcess:writeUint16(Protocol.NET_PLAYER_MOVE)
	self.msgProcess:writeInt32(self.localPlayerID)
	self.msgProcess:writeFloat(mapPos.x)
	self.msgProcess:writeFloat(mapPos.y)
	self.msgProcess:sendMsg(Protocol.NET_PLAYER_MOVE)
	lastPos = pt1
end

function World:sendMsg(msgType)
end

function World:receiveMsg(msgType)
	if msgType == Protocol.NET_PLAYER_ME_LOGIN then
		local playerID = self.msgProcess:readInt32()
		local locationX = self.msgProcess:readFloat()
		local locationY = self.msgProcess:readFloat()
		local life = self.msgProcess:readInt32()
		
		self.localPlayerID = playerID
		local player = LocalPlayer:create("player/player.cc2d", self)
		local winSize = CCDirector:sharedDirector():getWinSize()
		Player.move(player,ccpSub(CCPoint(locationX, locationY), player:getPositionLua()))
		local center = self.map:convertToNodeSpace(CCPoint(winSize.width*0.5, winSize.height*0.5))
		self.map:setPosition(center.x-locationX, center.y-locationY)
		player:setLife(life)
		self.players[playerID] = player
	elseif msgType == Protocol.NET_PLAYER_NEW_LOGIN then
		local playerID = self.msgProcess:readInt32()
		local locationX = self.msgProcess:readFloat()
		local locationY = self.msgProcess:readFloat()
		
		local player = Player:create("player/player.cc2d", self)
		Misc:log("new player :x="..locationX..",y="..locationY .."----ID="..playerID)
		player:setPosition(locationX, locationY)
		self.players[playerID] = player
	elseif msgType == Protocol.NET_MONSTER_NEW then
		local playerID = self.msgProcess:readInt32()
		local locationX = self.msgProcess:readFloat()
		local locationY = self.msgProcess:readFloat()
		
		local player = Player:create("monster/meihualu.cc2d", self)
		player.ccatFile = "monster/meihualu.ccat"
		Misc:log("new monster :x="..locationX..",y="..locationY .."----ID="..playerID)
		player:setPosition(locationX, locationY)
		self.players[playerID] = player
	elseif msgType == Protocol.NET_PLAYER_MOVE then
		local playerID = self.msgProcess:readInt32()
		local destLocationX = self.msgProcess:readFloat()
		local destLocationY = self.msgProcess:readFloat()
		
		Misc:log("new local player :x="..destLocationX..",y="..destLocationY .."----ID="..playerID)
		if self.players[playerID] then
			self.players[playerID]:moveTo(CCPoint(destLocationX, destLocationY))
		end
	elseif msgType == Protocol.NET_PLAYER_LOGOUT then
		local playerID = self.msgProcess:readInt32()
		
		Misc:log("NET_PLAYER_LOGOUT ".."----ID="..playerID)
		self.players[playerID]:removeFromParentAndCleanup(false)
		self.players[playerID] = nil
	elseif msgType == Protocol.NET_MONSTER_REMOVE then
		local playerID = self.msgProcess:readInt32()
		
		Misc:log("NET_MONSTER_REMOVE ".."----ID="..playerID)
		self.players[playerID]:removeFromParentAndCleanup(false)
		self.players[playerID] = nil
	end
end

World:create()